<template>
  <el-form label-position="top" v-if="data" :key="data.key">
    <el-form-item label="字段标识" v-if="data.type !== 'grid'">
      <el-input v-model="data.model" />
    </el-form-item>

    <el-form-item label="标题" v-if="data.type !== 'grid'">
      <el-input v-model="data.label" />
    </el-form-item>

    <el-form-item label="宽度" v-if="hasKey('width')">
      <el-input v-model="data.options.width" />
    </el-form-item>

    <el-form-item label="占位内容" v-if="hasKey('placeholder')">
      <el-input v-model="data.options.placeholder" />
    </el-form-item>

    <el-form-item
      label="默认内容"
      v-if="
        hasKey('defaultValue') &&
        (data.type === 'input' ||
          data.type === 'password' ||
          data.type === 'textarea' ||
          data.type === 'text' ||
          data.type === 'rate' ||
          data.type === 'switch' ||
          data.type === 'slider')
      "
    >
      <el-input
        v-if="data.type === 'input' || data.type === 'password' || data.type === 'text'"
        v-model="data.options.defaultValue"
      />
      <el-input type="textarea" v-if="data.type === 'textarea'" v-model="data.options.defaultValue" />
      <el-rate
        v-if="data.type === 'rate'"
        v-model="data.options.defaultValue"
        :max="data.options.max"
        :allow-half="data.options.allowHalf"
      />
      <el-switch v-if="data.type === 'switch'" v-model="data.options.defaultValue" />
      <template v-if="data.type === 'slider'">
        <el-input-number v-if="!data.options.range" v-model.number="data.options.defaultValue" />
        <template v-if="data.options.range">
          <el-input-number v-model.number="data.options.defaultValue[0]" :max="data.options.max" />
          <el-input-number v-model.number="data.options.defaultValue[1]" :max="data.options.max" />
        </template>
      </template>
    </el-form-item>

    <el-form-item label="最大长度" v-if="hasKey('maxlength')">
      <el-input v-model.number="data.options.maxlength" />
    </el-form-item>

    <el-form-item label="最大值" v-if="hasKey('max')">
      <el-input-number v-model.number="data.options.max" />
    </el-form-item>

    <el-form-item label="最小值" v-if="hasKey('min')">
      <el-input-number v-model.number="data.options.min" />
    </el-form-item>

    <el-form-item label="步长" v-if="hasKey('step')">
      <el-input-number v-model.number="data.options.step" :min="0" />
    </el-form-item>

    <el-form-item label="前缀" v-if="hasKey('prefix')">
      <el-input v-model="data.options.prefix" />
    </el-form-item>

    <el-form-item label="后缀" v-if="hasKey('suffix')">
      <el-input v-model="data.options.suffix" />
    </el-form-item>

    <el-form-item label="前置标签" v-if="hasKey('prepend')">
      <el-input v-model="data.options.prepend" />
    </el-form-item>

    <el-form-item label="后置标签" v-if="hasKey('append')">
      <el-input v-model="data.options.append" />
    </el-form-item>

    <el-form-item label="选中时的内容" v-if="hasKey('activeText')">
      <el-input v-model="data.options.activeText" />
    </el-form-item>

    <el-form-item label="非选中时的内容" v-if="hasKey('inactiveText')">
      <el-input v-model="data.options.inactiveText" />
    </el-form-item>

    <el-form-item label="文本框可输入" v-if="hasKey('editable')">
      <el-switch v-model="data.options.editable" />
    </el-form-item>

    <el-form-item label="范围选择" v-if="hasKey('range')">
      <el-switch v-model="data.options.range" @change="handleSliderModeChange" />
    </el-form-item>

    <el-form-item label="是否显示切换按钮" v-if="hasKey('showPassword')">
      <el-switch v-model="data.options.showPassword" />
    </el-form-item>

    <el-form-item label="是否显示字数" v-if="hasKey('showWordLimit')">
      <el-switch v-model="data.options.showWordLimit" />
    </el-form-item>

    <el-form-item label="是否自适应内容高度" v-if="hasKey('autosize')">
      <el-switch v-model="data.options.autosize" />
    </el-form-item>

    <el-form-item label="行数" v-if="hasKey('rows') && !data.options.autosize">
      <el-input-number v-model="data.options.rows" :min="0" />
    </el-form-item>

    <el-form-item label="是否允许半选" v-if="hasKey('allowHalf')">
      <el-switch v-model="data.options.allowHalf" />
    </el-form-item>

    <el-form-item label="布局方式" v-if="hasKey('inline')">
      <el-radio-group v-model="data.options.inline">
        <el-radio-button :value="true">行内</el-radio-button>
        <el-radio-button :value="false">块级</el-radio-button>
      </el-radio-group>
    </el-form-item>

    <el-form-item label="是否多选" v-if="hasKey('multiple')">
      <el-switch v-model="data.options.multiple" @change="handleSelectModeChange" />
    </el-form-item>

    <el-form-item label="是否可搜索" v-if="hasKey('filterable')">
      <el-switch v-model="data.options.filterable" />
    </el-form-item>

    <el-form-item label="是否显示标签" v-if="hasKey('showLabel')">
      <el-switch v-model="data.options.showLabel" />
    </el-form-item>

    <el-form-item label="选项" v-if="hasKey('options')">
      <el-radio-group v-model="data.options.remote">
        <el-radio-button :value="false">静态数据</el-radio-button>
        <el-radio-button :value="true">远端数据</el-radio-button>
      </el-radio-group>
      <el-space v-if="data.options.remote" alignment="start" direction="vertical" style="margin-top: 10px">
        <el-input v-model="data.options.remoteFunc">
          <template #prepend> 远端方法 </template>
        </el-input>
        <el-input v-model="data.options.props.label">
          <template #prepend> 标签 </template>
        </el-input>
        <el-input v-model="data.options.props.value">
          <template #prepend> 值 </template>
        </el-input>
      </el-space>
      <template v-else>
        <template v-if="data.type === 'radio' || (data.type === 'select' && !data.options.multiple)">
          <el-radio-group v-model="data.options.defaultValue" style="margin-top: 8px">
            <Draggable
              tag="ul"
              item-key="index"
              ghost-class="ghost"
              handle=".drag-item"
              :group="{ name: 'options' }"
              :list="data.options.options"
            >
              <template #item="{ element, index }">
                <div style="display: flex; align-items: center; margin-bottom: 5px">
                  <el-radio :label="element.value" style="margin-right: 0px; margin-bottom: 0">
                    <el-input
                      :style="{
                        width: data.options.showLabel ? '90px' : '180px'
                      }"
                      v-model="element.value"
                    />
                    <el-input
                      v-if="data.options.showLabel"
                      :style="{
                        width: '90px'
                      }"
                      v-model="element.label"
                    />
                  </el-radio>
                  <SvgIcon style="margin: 0 5px; cursor: move" name="item" class="drag-item" />
                  <el-button type="primary" circle @click="handleOptionsRemove(index)">
                    <SvgIcon name="delete" />
                  </el-button>
                </div>
              </template>
            </Draggable>
          </el-radio-group>
        </template>

        <template v-if="data.type === 'checkbox' || (data.type === 'select' && data.options.multiple)">
          <el-checkbox-group v-model="data.options.defaultValue" style="margin-top: 8px">
            <Draggable
              tag="ul"
              item-key="index"
              ghost-class="ghost"
              handle=".drag-item"
              :group="{ name: 'options' }"
              :list="data.options.options"
            >
              <template #item="{ element, index }">
                <li style="display: flex; align-items: center; margin-bottom: 5px">
                  <el-checkbox :label="element.value" style="margin-right: 0px; margin-bottom: 0">
                    <el-input
                      :style="{
                        width: data.options.showLabel ? '90px' : '180px'
                      }"
                      v-model="element.value"
                    />
                    <el-input v-if="data.options.showLabel" v-model="element.label" :style="{ width: '90px' }" />
                  </el-checkbox>
                  <SvgIcon style="margin: 0 5px; cursor: move" name="item" class="drag-item" />
                  <el-button type="primary" circle @click="handleOptionsRemove(index)">
                    <SvgIcon name="delete" />
                  </el-button>
                </li>
              </template>
            </Draggable>
          </el-checkbox-group>
        </template>

        <div style="margin-top: 5px">
          <el-button type="text" @click="handleInsertOption">添加选项</el-button>
        </div>
      </template>
    </el-form-item>

    <template v-if="data.type === 'time'">
      <el-form-item label="默认值">
        <el-time-picker
          style="width: 100%"
          v-model="data.options.defaultValue"
          :format="data.options.format"
          :placeholder="data.options.placeholder"
        />
      </el-form-item>
    </template>

    <template v-if="data.type === 'date'">
      <el-form-item label="默认值">
        <el-date-picker
          style="width: 100%"
          v-model="data.options.defaultValue"
          :format="data.options.format"
          :placeholder="data.options.placeholder"
        />
      </el-form-item>
    </template>

    <template v-if="data.type === 'time' || data.type === 'date'">
      <el-form-item label="格式">
        <el-input v-model="data.options.format" />
      </el-form-item>
    </template>

    <template v-if="data.type === 'img-upload'">
      <el-form-item label="模式">
        <el-radio-group v-model="data.options.listType">
          <el-radio-button value="text">text</el-radio-button>
          <el-radio-button value="picture">picture</el-radio-button>
          <el-radio-button value="picture-card">picture-card</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="文件参数名">
        <el-input v-model="data.options.name" />
      </el-form-item>

      <el-form-item label="上传地址">
        <el-input v-model="data.options.action" />
      </el-form-item>

      <el-form-item label="接受上传的文件类型(多个使用 , 隔开)">
        <el-input v-model="data.options.accept" />
      </el-form-item>

      <el-form-item label="最大上传数量">
        <el-input-number v-model.number="data.options.limit" :min="1" />
      </el-form-item>

      <el-form-item label="上传请求方法">
        <el-radio-group v-model="data.options.method">
          <el-radio-button value="post">POST</el-radio-button>
          <el-radio-button value="put">PUT</el-radio-button>
          <el-radio-button value="get">GET</el-radio-button>
          <el-radio-button value="delete">DELETE</el-radio-button>
        </el-radio-group>
      </el-form-item>
    </template>

    <el-form-item label="远端数据" v-if="data.type === 'cascader'">
      <el-space direction="vertical" alignment="start">
        <el-input v-model="data.options.remoteFunc">
          <template #prepend> 远端方法 </template>
        </el-input>
        <el-input v-model="data.options.props.label">
          <template #prepend> 标签 </template>
        </el-input>
        <el-input v-model="data.options.props.value">
          <template #prepend> 值 </template>
        </el-input>
        <el-input v-model="data.options.props.children">
          <template #prepend> 子选项 </template>
        </el-input>
      </el-space>
    </el-form-item>

    <template v-if="data.type === 'grid'">
      <el-form-item label="栅格间隔">
        <el-input-number v-model.number="data.options.gutter" :min="0" />
      </el-form-item>

      <el-form-item label="列配置项">
        <Draggable
          tag="ul"
          item-key="index"
          ghost-class="ghost"
          handle=".drag-item"
          :group="{ name: 'options' }"
          :list="data.columns"
        >
          <template #item="{ element, index }">
            <li style="margin-bottom: 5px">
              <SvgIcon name="item" class="drag-item" />
              <el-input-number placeholder="栅格值" v-model.number="element.span" :min="0" :max="24" />
              <el-button type="primary" circle style="margin-left: 5px" @click="handleOptionsRemove(index)">
                <SvgIcon name="delete" />
              </el-button>
            </li>
          </template>
        </Draggable>

        <div>
          <el-button type="text" @click="handleInsertColumn"> 添加列 </el-button>
        </div>
      </el-form-item>

      <el-form-item label="垂直对齐方式">
        <el-radio-group v-model="data.options.align">
          <el-radio-button value="top">顶部对齐</el-radio-button>
          <el-radio-button value="middle">居中对齐</el-radio-button>
          <el-radio-button value="bottom">底部对齐</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="水平排列方式">
        <el-select v-model="data.options.justify">
          <el-option value="start" label="左对齐" />
          <el-option value="end" label="右对齐" />
          <el-option value="center" label="居中" />
          <el-option value="space-around" label="两侧间隔相等" />
          <el-option value="space-between" label="两端对齐" />
        </el-select>
      </el-form-item>
    </template>

    <template v-if="data.type !== 'grid'">
      <el-form-item label="操作属性" v-if="hasKey('rules') || hasKey('readonly') || hasKey('disabled') || hasKey('allowClear')">
        <el-checkbox v-if="hasKey('rules')" v-model="data.options.rules.required">必填</el-checkbox>
        <el-checkbox v-if="hasKey('readonly')" v-model="data.options.readonly">只读</el-checkbox>
        <el-checkbox v-if="hasKey('disabled')" v-model="data.options.disabled">禁用</el-checkbox>
        <el-checkbox v-if="hasKey('clearable')" v-model="data.options.clearable">清除</el-checkbox>
      </el-form-item>

      <template v-if="hasKey('rules')">
        <h4>验证规则</h4>

        <el-form-item label="触发时机">
          <el-radio-group v-model="data.options.rules.trigger">
            <el-radio-button value="blur">Blur</el-radio-button>
            <el-radio-button value="change">Change</el-radio-button>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="枚举类型">
          <el-input v-model="data.options.rules.enum" />
        </el-form-item>

        <el-form-item label="字段长度">
          <el-input v-model.number="data.options.rules.len" />
        </el-form-item>

        <el-form-item label="最大长度">
          <el-input v-model.number="data.options.rules.max" />
        </el-form-item>

        <el-form-item label="最小长度">
          <el-input v-model.number="data.options.rules.min" />
        </el-form-item>

        <el-form-item label="校验文案">
          <el-input v-model="data.options.rules.message" />
        </el-form-item>

        <el-form-item label="正则表达式">
          <el-input v-model="data.options.rules.pattern" />
        </el-form-item>

        <el-form-item label="校验类型">
          <el-select v-model="data.options.rules.type">
            <el-option value="string">字符串</el-option>
            <el-option value="number">数字</el-option>
            <el-option value="boolean">布尔值</el-option>
            <el-option value="method">方法</el-option>
            <el-option value="regexp">正则表达式</el-option>
            <el-option value="integer">整数</el-option>
            <el-option value="float">浮点数</el-option>
            <el-option value="array">数组</el-option>
            <el-option value="object">对象</el-option>
            <el-option value="enum">枚举</el-option>
            <el-option value="date">日期</el-option>
            <el-option value="url">URL地址</el-option>
            <el-option value="hex">十六进制</el-option>
            <el-option value="email">邮箱地址</el-option>
            <el-option value="any">任意类型</el-option>
          </el-select>
        </el-form-item>
      </template>
    </template>
  </el-form>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import Draggable from 'vuedraggable';
import SvgIcon from '@/components/SvgIcon/index.vue';

const props = defineProps({
  select: {
    type: Object
  }
});

const emit = defineEmits(['update:select']);

const data = ref<any>(props.select);

watch(
  () => props.select,
  val => (data.value = val)
);

watch(data, val => emit('update:select', val), { deep: true });

const hasKey = (key: string) => Object.keys(data.value.options).includes(key);

const handleInsertColumn = () => {
  data.value.columns.push({
    span: 0,
    list: []
  });
};

const handleInsertOption = () => {
  const index = data.value.options.options.length + 1;
  data.value.options.options.push({
    label: `Option ${index}`,
    value: `Option ${index}`
  });
};

const handleOptionsRemove = (index: number) => {
  if (data.value.type === 'grid') {
    data.value.columns.splice(index, 1);
  } else {
    data.value.options.options.splice(index, 1);
  }
};

const handleSliderModeChange = (checked: boolean) => {
  checked ? (data.value.options.defaultValue = [10, 90]) : (data.value.options.defaultValue = 0);
};

const handleSelectModeChange = (val: boolean) => {
  if (data.value.type === 'img-upload') {
    return;
  }
  if (val) {
    if (data.value.options.defaultValue) {
      if (!(data.value.options.defaultValue instanceof Array)) {
        data.value.options.defaultValue = [data.value.options.defaultValue];
      }
    } else {
      data.value.options.defaultValue = [];
    }
  } else {
    data.value.options.defaultValue.length
      ? (data.value.options.defaultValue = data.value.options.defaultValue[0])
      : (data.value.options.defaultValue = null);
  }
};
</script>
